package GoogleHandler;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.gdata.client.Query;
import com.google.gdata.client.calendar.CalendarQuery;
import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.calendar.CalendarEntry;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.calendar.CalendarEventFeed;
import com.google.gdata.data.calendar.CalendarFeed;
import com.google.gdata.data.calendar.EventWho;
import com.google.gdata.data.extensions.When;
import com.google.gdata.data.extensions.Where;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;

public class GoogleEx2
{

    int entriesFound = 0;

    String feedAdress = "http://www.google.com/calendar/feeds/sistemintel@gmail.com/private/full";

    CalendarEventFeed myResultsFeed = null;

    // create a calendar service
    CalendarService myService = new CalendarService("gCalendar Service 0.1");

    String password = "calimeri";

    String resultString = "";

    String username = "sistemintel@gmail.com";

    public Integer doQueryByTimeRange(final String start, final String end, final String feedAdress, final String user,
            final String pwd)
    {

        URL feedURL = null;
        try
        {
            // request the list of all calendars from the authenticated user
            feedURL = new URL(feedAdress);
        }
        catch (final MalformedURLException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
        }
        // create a new query object and set the parameters
        final CalendarQuery myQuery = new CalendarQuery(feedURL);
        myQuery.setMinimumStartTime(DateTime.parseDateTime(start));
        myQuery.setMaximumStartTime(DateTime.parseDateTime(end));

        // send the request with the built query URL
        try
        {
            myResultsFeed = myService.query(myQuery, CalendarEventFeed.class);
        }
        catch (final IOException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (final ServiceException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
        }

        entriesFound = myResultsFeed.getEntries().size();
        System.out.println("java: FEEDS WITH " + "Given Time Range" + " FOUND: " + entriesFound);
        System.out.println();
        System.out.println("####################");
        return entriesFound;
    }

    // do a query to the calendar service
    public Integer doQueryByTitle(final String searchTerm, final String feedAdress, final String user, final String pwd)
    {

        URL feedURL = null;
        try
        {
            // request the list of all calendars from the authenticated user
            feedURL = new URL(feedAdress);
        }
        catch (final MalformedURLException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
        }
        // create a new query object and set the parameters
        final Query myQuery = new Query(feedURL);
        myQuery.setFullTextQuery(searchTerm);

        // send the request with the built query URL
        try
        {
            myResultsFeed = myService.query(myQuery, CalendarEventFeed.class);
        }
        catch (final IOException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (final ServiceException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
        }

        entriesFound = myResultsFeed.getEntries().size();
        System.out.println("java: FEEDS WITH " + searchTerm + " FOUND: " + entriesFound);
        System.out.println();
        System.out.println("####################");
        return entriesFound;
    }

    // method not yet used in the interface, we are handling only one calendar for version 0.01
    public void getCalendars()
    {
        URL feedUrl = null;
        try
        {
            // request the list of all calendars from the authenticated user
            feedUrl = new URL("http://www.google.com/calendar/feeds/default/allcalendars/full");
        }
        catch (final MalformedURLException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
        }
        CalendarFeed resultFeed = null;
        try
        {
            // execute GET command on the URL and put the resultant feed into a tidy object
            resultFeed = myService.getFeed(feedUrl, CalendarFeed.class);
        }
        catch (final IOException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (final ServiceException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println("Your calendars:");
        System.out.println();

        // iterate through each entry and print the title (stored as a TextConstruct - getPlainText for text)
        for (int i = 0; i < resultFeed.getEntries().size(); i++)
        {
            final CalendarEntry entry = resultFeed.getEntries().get(i);
            System.out.println("\t" + entry.getTitle().getPlainText());
        }
    }

    // return the whole event data (time | title | location) at given position
    public String getQueryResults(final int elementAt)
    {

        final int num_participants = myResultsFeed.getEntries().get(elementAt).getParticipants().size();

        // get event time + title, elements of results feed
        resultString = "EVENT START AT: "
                + myResultsFeed.getEntries().get(elementAt).getTimes().get(0).getStartTime().toUiString() + " | EVENT END AT: "
                + myResultsFeed.getEntries().get(elementAt).getTimes().get(0).getEndTime().toUiString() + "| EVENT TITLE: "
                + myResultsFeed.getEntries().get(elementAt).getTitle().getPlainText() + "| EVENT DESCRIPTION: "
                + myResultsFeed.getEntries().get(elementAt).getPlainTextContent();
        // try to receive location if set
        String location = null;
        try
        {
            location = myResultsFeed.getEntries().get(elementAt).getLocations().get(0).getValueString().toString();
        }
        catch (final Exception e)
        {
            //System.out.println("java: INVALID Location specified!!");
            //return "INCOMPLETE ENTRY IS: " + myResultsFeed.getEntries().get(elementAt).getTitle().getPlainText();
        }
        // if location is not available add ---
        if (location == null || location.equals(""))
        {
            location = "---";
        }
        resultString += " | EVENT LOCATION: " + location;
        System.out.println("java: " + resultString);
        System.out.println("EVENT PARTICIPANTS:");

        for (int i = 0; i < num_participants; i++)
        {
            System.out.println(myResultsFeed.getEntries().get(elementAt).getParticipants().get(i).getEmail().toString());
        }
        System.out.println("####################");
        return resultString;
    }

    // return all the events found as String Array
    public String[] getQueryResultsArray()
    {
        // create a new array with number of feeds found
        final String[] strArray = new String[myResultsFeed.getEntries().size()];
        // iterate of all events and save data in string array
        for (int i = 0; i < myResultsFeed.getEntries().size(); i++)
        {
            strArray[i] = myResultsFeed.getEntries().get(i).getTimes().get(0).getStartTime().toUiString() + " | "
                    + myResultsFeed.getEntries().get(i).getTitle().getPlainText();
            // care for locations
            String location = null;
            try
            {
                location = myResultsFeed.getEntries().get(i).getLocations().get(0).getValueString().toString();
            }
            catch (final Exception e)
            {
                System.out.println("java: INVALID Location specified!!");
            }
            if (location == null || location.equals(""))
            {
                location = "---";
            }
            // write to array
            strArray[i] += " | " + location;
        }

        // sort the string array!
        java.util.Arrays.sort(strArray);
        // to set special Locale chose: (strArray, java.text.Collator.getInstance(Locale.ENGLISH));

        // return all the data fetched 
        return strArray;
    }

    // returns in format: 2009-01-15
    public String getToday()
    {
        String today = DateTime.now().toUiString(); // "2009-01-19T11:21:26.256Z"
        today = today.substring(0, 10);
        return today;
    }

    // new calendar event entry
    public Boolean setEvent(final String feedAdress, final String eventTitle, final String eventDescription,
            final String eventLocation, final String eventStart, final String eventEnd)
    {
        System.out.println("Setting event: \n Title: " + eventTitle + "\n Event Description: " + eventDescription
                + "\n Event Location: " + eventLocation + "\n Event Start At: " + eventStart + "\n Event End At:" + eventEnd);
        URL postURL = null;
        try
        {
            postURL = new URL(feedAdress);
        }
        catch (final MalformedURLException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
        }

        final CalendarEventEntry myEvent = new CalendarEventEntry();

        // set title and description
        myEvent.setTitle(new PlainTextConstruct(eventTitle));

        // create DateTime events and create a When object to hold them
        // then add the When event to the event
        final DateTime startTime = DateTime.parseDateTime(eventStart); // "2009-01-15T15:00:00-08:00"
        final DateTime endTime = DateTime.parseDateTime(eventEnd); // "2009-01-15T17:00:00-08:00"
        final When eventTimes = new When();
        eventTimes.setStartTime(startTime);
        eventTimes.setEndTime(endTime);
        myEvent.addTime(eventTimes);
        // add a Where object to add the location
        final Where eventPlace = new Where();
        eventPlace.setValueString(eventLocation);
        myEvent.addLocation(eventPlace);

        //

        // ADDING Participants

        final EventWho who = new EventWho();
        who.setEmail("paolo@firmo.net");
        myEvent.addParticipant(who);
        myEvent.setSendEventNotifications(true);
        try
        {
            // POST the request and receive the response
            myService.insert(postURL, myEvent);
        }
        catch (final IOException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        catch (final ServiceException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        System.out.println("java: ENTRY ADDED to Calendar!");
        // return true if posting worked without any errors
        return true;
    }

    Boolean authenticate(final String user, final String pwd)
    {
        System.out.println("java: TRYING TO AUTHENTICATE...");
        username = user;
        password = pwd;
        try
        {
            // Authenticate using ClientLogin
            myService.setUserCredentials(user, pwd);
        }
        catch (final AuthenticationException ex)
        {
            Logger.getLogger(CalendarService.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("java: CANNOT ESTABLISH CONNECTION!");
            return false;
        }
        System.out.println("java: ...CONNECTED!");
        return true;
    }
}
